import bcrypt

from config.exceptions import NotFoundError, ExistError
from models.user import User
from repositories.role_repositories import RoleRepository
from repositories.user_repositories import UserRepository
from schemas.users import UserCreate, UserUpdate


class UserService:
    def __init__(self, user_repo: UserRepository, role_repo: RoleRepository):
        self.user_repo = user_repo
        self.role_repo = role_repo


    def validate_user_exists(self, user_data: UserCreate) -> bool:
        if self.user_repo.get_user_by_email(user_data.email):
            raise ExistError("邮箱已存在")
        if self.user_repo.get_user_by_phone_number(user_data.phone_number):
            raise ExistError("手机号已存在")
        if self.user_repo.get_user_by_username(user_data.username):
            raise ExistError("用户名已存在")
        return False

    def create_user(self, user_data: UserCreate) -> User:
        self.validate_user_exists(user_data)

        # 密码加密bcrypt
        hashed_password = bcrypt.hashpw(user_data.password.encode('utf-8'), bcrypt.gensalt())
        user_data.password = hashed_password.decode('utf-8')

        # 遍历用户角色
        user_role = []
        for role_id in user_data.roles:
            if not self.role_repo.get_role_by_id(role_id):
                raise ValueError("角色不存在")
            user_role.append(self.role_repo.get_role_by_id(role_id))

        user_data.roles = user_role

        user_data = User.model_validate(user_data)

        return self.user_repo.create_or_update_user(user_data)


    def delete_user(self, user_id: int):
        user = self.user_repo.get_user_by_id(user_id)
        if not user:
            raise NotFoundError("用户不存在")
        return self.user_repo.delete_user(user_id)


    def update_user(self, user_data: UserUpdate) -> User:
        user = self.user_repo.get_user_obj_by_id(user_data.id)
        if not user:
            raise NotFoundError("用户不存在")

        self.validate_user_exists(user_data)

        user_role = []
        for role_id in user_data.roles:
            if not self.role_repo.get_role_by_id(role_id):
                raise NotFoundError('角色不存在')
            user_role.append(self.role_repo.get_role_by_id(role_id))
        user_data.roles = user_role

        user.sqlmodel_update(user_data)

        return self.user_repo.create_or_update_user(user)

    def filter_user(self, page: int | None, size: int | None, username: str | None = None) -> list[User]:
        return self.user_repo.filter_user(page, size, username)


    def get_user_by_id(self, user_id: int) -> User:
        if not self.user_repo.get_user_by_id(user_id):
            raise NotFoundError("用户不存在")
        return self.user_repo.get_user_by_id(user_id)